home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_214 / mandelvroom / src / savemand.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  22KB  |  866 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains the functions to save projects to disk,
  25.  * load projects from disk, and save icon files (if the program was started
  26.  * from the WorkBench.)
  27.  */
  28.  
  29. #include "mandp.h"
  30.  
  31. extern struct NewScreen NewScreen;
  32.  
  33. extern ULONG CalcTime;
  34.  
  35. extern BYTE FromWB;
  36.  
  37.        ULONG BorderType;
  38.  
  39. USHORT  MandimageData1[] = {
  40.  0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0,
  41.  0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0,
  42.  0xFFFF, 0xFFE3, 0xFFFF, 0xFFC0,
  43.  0xFFFF, 0xF101, 0x67FF, 0xFFC0,
  44.  0xFFF8, 0x7040, 0xC0F7, 0xFFC0,
  45.  0xF9D4, 0x4441, 0x414B, 0xFFC0,
  46.  0xF80F, 0x0F79, 0x8403, 0xFFC0,
  47.  0xDA0F, 0xFFFF, 0xEC01, 0xFFC0,
  48.  0x9743, 0xFFFF, 0xFE46, 0x0FC0,
  49.  0x8FFF, 0xFFFF, 0xFF80, 0x3FC0,
  50.  0xF03F, 0xFFEF, 0xFFC0, 0x7FC0,
  51.  0xB7FF, 0xFE00, 0x3F91, 0xDFC0,
  52.  0xFFFF, 0xF878, 0x3FC0, 0x07C0,
  53.  0x8FFF, 0xF8F0, 0x7F80, 0x17C0,
  54.  0xB7FF, 0xF0FF, 0xFFC0, 0x3FC0,
  55.  0xFFFF, 0xF83F, 0xFC03, 0x7FC0,
  56.  0xFFFF, 0xF70F, 0xD801, 0xFFC0,
  57.  0xFFFF, 0xFE00, 0x0000, 0xFFC0,
  58.  0xBFFF, 0xFE50, 0x415C, 0xFFC0,
  59.  0xBFFF, 0xFFFC, 0x90FF, 0xFFC0,
  60.  0xFFFF, 0xFFFD, 0xFEFF, 0xFFC0,
  61.  0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0,
  62. /**/
  63.  0x01E0, 0xE1F0, 0xFC03, 0xFE00,
  64.  0x41E1, 0xC78F, 0xC03F, 0xF800,
  65.  0x61C7, 0x2BDD, 0xE1FF, 0x0000,
  66.  0x4394, 0x7FFF, 0xFD80, 0x0000,
  67.  0x4C57, 0xFFBF, 0x7FFD, 0xFFC0,
  68.  0x1FBB, 0xFFFF, 0xBFB4, 0x3FC0,
  69.  0x6FF0, 0xFCCF, 0xFFFC, 0xC1C0,
  70.  0x65F3, 0xF9C4, 0xB7FF, 0x9C00,
  71.  0x79FF, 0x8F33, 0x6BBD, 0xFB00,
  72.  0x70E7, 0xF136, 0x667F, 0xF9C0,
  73.  0x4FE0, 0x19D4, 0x0D3F, 0xD8C0,
  74.  0x4E9F, 0xC9FF, 0xC3EE, 0x3440,
  75.  0x6580, 0x67D7, 0xECBF, 0xFB00,
  76.  0x7A3E, 0x2FBF, 0x9EFF, 0xFF80,
  77.  0x69FF, 0xCF2A, 0xA3FF, 0xF580,
  78.  0x6700, 0x67E6, 0xC7FD, 0xB1C0,
  79.  0x583F, 0x1AF4, 0xA7FF, 0xF3C0,
  80.  0x31FF, 0xF5FF, 0xFFFF, 0x73C0,
  81.  0x53E0, 0x1DAF, 0xFEA7, 0x23C0,
  82.  0x4700, 0x00E7, 0xEF58, 0xE1C0,
  83.  0x4E07, 0xFFE3, 0x77E3, 0xC1C0,
  84.  0x383F, 0xFC00, 0x078F, 0x81C0,
  85. /**/
  86.  };
  87.  
  88. struct Image Mandimage1 = {
  89.  0,  /* LeftEdge */
  90.  0,  /* TopEdge */
  91.  58,  /* Width */
  92.  22,  /* Height */
  93.  2,  /* Depth */
  94.  (USHORT *)MandimageData1,  /* ImageData */
  95.  0xFF,  /* PlanePick */
  96.  0x0,  /* PlaneOnOff */
  97.  0,  /* [NextImage] */
  98.  };
  99.  
  100. struct DiskObject MandIcon = {
  101.  WB_DISKMAGIC,   /* do_Magic */
  102.  WB_DISKVERSION, /* do_Version */
  103.  
  104. /* Embedded Gadget Structure */
  105.  0,  /* [NextGadget] */
  106.  23,  /* LeftEdge */
  107.  14,  /* TopEdge */
  108.  58,  /* Width */
  109.  23,  /* Height */
  110.  0x5,  /* Flags */
  111.  0x3,  /* Activation */
  112.  0x1,  /* GadgetType */
  113.  (APTR)&Mandimage1, /* GadgetRender */
  114.  NULL,     /* SelectRender */
  115.  NULL,     /* GadgetText */
  116.  0x0,  /* MutualExclude */
  117.  0x0,  /* [SpecialInfo] */
  118.  0,  /* GadgetID */
  119.  0x0,  /* [UserData] */
  120.  
  121. /* Rest of DiskObject structure */
  122.  0x4,  /* do_Type */
  123.  "MandelBrot:MandelVroom",   /* do_Default Tool */
  124.  0x0,  /* [do_ToolTypes] */
  125.  0x80000000,  /* do_CurrentX */
  126.  0x80000000,  /* do_CurrentY */
  127.  0x0,  /* [do_DrawerData] */
  128.  0x0,  /* [do_ToolWindow] */
  129.  10240 /* do_StackSize */
  130.  };
  131.  
  132. USHORT  JuliaimageData1[] = {
  133.  0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  134.  0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  135.  0x0000, 0x0000, 0x0F80, 0x0000, 0x0000,
  136.  0x0000, 0x0000, 0x7F60, 0x0000, 0x0000,
  137.  0x0000, 0x000F, 0xF07E, 0x0000, 0x0000,
  138.  0x0000, 0x0079, 0xC071, 0xC000, 0x0000,
  139.  0x0004, 0xFFDB, 0xFFFE, 0xFC00, 0x0000,
  140.  0x001C, 0x6FDF, 0xFFFF, 0xFF7D, 0x0000,
  141.  0x00FF, 0xF183, 0xFFE0, 0x73C3, 0xC000,
  142.  0x05FF, 0xF100, 0x7FE0, 0xC3FF, 0xFC00,
  143.  0x33C3, 0xFC00, 0x7FFE, 0x007C, 0x6D80,
  144.  0x1F85, 0xF800, 0xFFF8, 0x007F, 0x0670,
  145.  0x03F1, 0xFC06, 0x3FF0, 0x01FE, 0x03E0,
  146.  0x003B, 0xFF98, 0x0FF0, 0x021F, 0xDF80,
  147.  0x000F, 0x187C, 0x3FFF, 0xE6FE, 0xB000,
  148.  0x0003, 0xFFFD, 0xFFFF, 0xDFC1, 0xC000,
  149.  0x0000, 0x003E, 0x7FDF, 0x7FFF, 0x0000,
  150.  0x0000, 0x0006, 0x785B, 0x6000, 0x0000,
  151.  0x0000, 0x0000, 0xFC7E, 0x0000, 0x0000,
  152.  0x0000, 0x0000, 0x1BF0, 0x0000, 0x0000,
  153.  0x0000, 0x0000, 0x0380, 0x0000, 0x0000,
  154.  0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  155. /**/
  156.  0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  157.  0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  158.  0x0000, 0x0000, 0x0D80, 0x0000, 0x0000,
  159.  0x0000, 0x0000, 0x70E0, 0x0000, 0x0000,
  160.  0x0000, 0x000F, 0xFFFE, 0x0000, 0x0000,
  161.  0x0000, 0x007E, 0x3F8F, 0xC000, 0x0000,
  162.  0x0007, 0xFFF4, 0x0001, 0xFC00, 0x0000,
  163.  0x001F, 0x93E0, 0x0000, 0xFFF3, 0x0000,
  164.  0x00F0, 0x0FFC, 0x001F, 0xFC3D, 0xC000,
  165.  0x0660, 0x0FFF, 0x801F, 0xFC00, 0x7C00,
  166.  0x2C7C, 0x1FFF, 0x9FFF, 0xFF83, 0xF380,
  167.  0x1C7E, 0x07FF, 0xFFFF, 0xFF83, 0xF990,
  168.  0x03FE, 0x03FF, 0xFF8F, 0xFFC1, 0xFC60,
  169.  0x003C, 0x007F, 0xF00F, 0xFFE0, 0x3F80,
  170.  0x000F, 0xE7FB, 0xC000, 0x1F03, 0x7000,
  171.  0x0002, 0xFFFE, 0x0000, 0x3FFE, 0xC000,
  172.  0x0000, 0x003F, 0x80A1, 0xFFFF, 0x0000,
  173.  0x0000, 0x0007, 0xC7E6, 0xE000, 0x0000,
  174.  0x0000, 0x0000, 0xFFBE, 0x0000, 0x0000,
  175.  0x0000, 0x0000, 0x1C70, 0x0000, 0x0000,
  176.  0x0000, 0x0000, 0x0280, 0x0000, 0x0000,
  177.  0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  178. /**/
  179.  };
  180.  
  181. struct Image Juliaimage1 = {
  182.  0,  /* LeftEdge */
  183.  0,  /* TopEdge */
  184.  78,  /* Width */
  185.  22,  /* Height */
  186.  2,  /* Depth */
  187.  (USHORT *)JuliaimageData1,  /* ImageData */
  188.  0xFF,  /* PlanePick */
  189.  0x0,  /* PlaneOnOff */
  190.  0,  /* [NextImage] */
  191.  };
  192.  
  193. struct DiskObject JuliaIcon = {
  194.  WB_DISKMAGIC,   /* do_Magic */
  195.  WB_DISKVERSION, /* do_Version */
  196.  
  197. /* Embedded Gadget Structure */
  198.  0,  /* [NextGadget] */
  199.  23,  /* LeftEdge */
  200.  14,  /* TopEdge */
  201.  78,  /* Width */
  202.  23,  /* Height */
  203.  0x5,  /* Flags */
  204.  0x3,  /* Activation */
  205.  0x1,  /* GadgetType */
  206.  (APTR)&Juliaimage1, /* GadgetRender */
  207.  NULL,     /* SelectRender */
  208.  NULL,     /* GadgetText */
  209.  0x0,  /* MutualExclude */
  210.  0x0,  /* [SpecialInfo] */
  211.  0,  /* GadgetID */
  212.  0x0,  /* [UserData] */
  213.  
  214. /* Rest of DiskObject structure */
  215.  0x4,  /* do_Type */
  216.  "MandelBrot:MandelVroom",   /* do_Default Tool */
  217.  0x0,  /* [do_ToolTypes] */
  218.  0x80000000,  /* do_CurrentX */
  219.  0x80000000,  /* do_CurrentY */
  220.  0x0,  /* [do_DrawerData] */
  221.  0x0,  /* [do_ToolWindow] */
  222.  10240 /* do_StackSize */
  223.  };
  224.  
  225. /*
  226.  * Save all the data needed to restore the system to current state.
  227.  */
  228. int
  229. SaveCounts(SaveName, Pict)
  230.   register char *SaveName;
  231.   register struct Picture *Pict;
  232. {
  233.   register FILE  *SaveFile;
  234.  
  235.   USHORT ViewModes;
  236.   UBYTE  Depth;
  237.   ULONG  Version = VERSION;
  238.   char   ErrMsg[80];
  239.  
  240.   /*
  241.    * Change the mouse pointer to Sleepy pointer
  242.    */
  243.   SetSleepyPointer();
  244.  
  245.   /*
  246.    * open the desired file for writing
  247.    */
  248.   SaveFile = fopen(SaveName,"w");
  249.  
  250.   if (SaveFile == (FILE *) NULL) {
  251.     sprintf(ErrMsg, "Can't open file %s", SaveName);
  252.     DispErrMsg(ErrMsg, 0);
  253.     return(UNSUCCESSFUL);
  254.   }
  255.  
  256.   Pict->LeftEdge = Pict->Window->LeftEdge;
  257.   Pict->TopEdge  = Pict->Window->TopEdge;
  258.  
  259.   /*
  260.    * if there is data to save, save it
  261.    */
  262.   if (Pict->Counts && ! (Pict->Flags & NO_RAM_GENERATE) ) {
  263.  
  264.     if (Pict->pNode.ln_Type == MANDPICT) {
  265.  
  266.       /*
  267.        * Put out the file header
  268.        */
  269.       fwrite((char *) "MAN4",    4,  1, SaveFile);
  270.     } else {
  271.  
  272.       /*
  273.        * Put out the file header
  274.        */
  275.       fwrite((char *) "JUL4",    4,  1, SaveFile);
  276.     }
  277.  
  278.     /*
  279.      * Put out the revision number
  280.      */
  281.     fwrite((char *) Version,   sizeof(Version), 1, SaveFile);
  282.  
  283.     if (Pict->pNode.ln_Type == JULIAPICT) {
  284.  
  285.       /*
  286.        * Put out the Julia point
  287.        */
  288.       fwrite((char *) &Pict->Real,   sizeof(double),   1, SaveFile);
  289.       fwrite((char *) &Pict->Imag,   sizeof(double),   1, SaveFile);
  290.     }
  291.  
  292.     /*
  293.      * Put out the location on the complex plane
  294.      */
  295.     fwrite((char *) &Pict->RealLow,   sizeof(double),   1, SaveFile);
  296.     fwrite((char *) &Pict->ImagLow,   sizeof(double),   1, SaveFile);
  297.     fwrite((char *) &Pict->RealHigh,  sizeof(double),   1, SaveFile);
  298.     fwrite((char *) &Pict->ImagHigh,  sizeof(double),   1, SaveFile);
  299.  
  300.     /*
  301.      * Put out the Maximum iteration count for a given point
  302.      */
  303.     fwrite((char *) &Pict->MaxIteration, sizeof(SHORT),    1, SaveFile);
  304.  
  305.     /*
  306.      * Put out the generator type
  307.      */
  308.     fwrite((char *) &Pict->MathMode, sizeof(Pict->MathMode), 1, SaveFile);
  309.  
  310.     /*
  311.      * Put out the time it took to generate
  312.      */
  313.     fwrite((char *) &CalcTime, sizeof(CalcTime), 1, SaveFile);
  314.  
  315.     /*
  316.      * Put out the screen's viewmodes
  317.      */
  318.     ViewModes = NewScreen.ViewModes;
  319.     fwrite((char *) &ViewModes, sizeof(ViewModes), 1, SaveFile);
  320.  
  321.     /*
  322.      * Put out the number of bit planes
  323.      */
  324.     Depth = NewScreen.Depth;
  325.     fwrite((char *) &Depth, sizeof(Depth), 1, SaveFile);
  326.  
  327.     /*
  328.      * Put some window flags
  329.      */
  330.     fwrite((char *) &BorderType, sizeof(BorderType), 1, SaveFile);
  331.  
  332.     /*
  333.      * Save the Color Palette
  334.      */
  335.     fwrite((char *) &Pict->RGBs, sizeof(Pict->RGBs), 1, SaveFile);
  336.  
  337.     /*
  338.      * Save the number of contours
  339.      */
  340.     fwrite((char *) &NumContours, sizeof(NumContours), 1, SaveFile);
  341.  
  342.     /*
  343.      * Save the contour's heights
  344.      */
  345.     fwrite((char *) Pict->Heights, sizeof(SHORT), (int) NumContours, SaveFile);
  346.  
  347.     /*
  348.      * Save the contour's pen numbers (Color is a misnomer)
  349.      */
  350.     fwrite((char *) Pict->Pens, sizeof(UBYTE), (int) NumContours, SaveFile);
  351.  
  352.     /*
  353.      * Put out the image dimensions
  354.      */
  355.     fwrite((char *) &Pict->CountX,   sizeof(SHORT),   1, SaveFile);
  356.     fwrite((char *) &Pict->CountY,   sizeof(SHORT),   1, SaveFile);
  357.  
  358.     /*
  359.      * Put out project's position
  360.      */
  361.     fwrite((char *) &Pict->LeftEdge, sizeof(Pict->LeftEdge), 1, SaveFile);
  362.     fwrite((char *) &Pict->TopEdge,  sizeof(Pict->TopEdge),  1, SaveFile);
  363.     fwrite((char *) &Pict->CurLine,  sizeof(Pict->CurLine),  1, SaveFile);
  364.  
  365.     (void) WriteRLLTwo( SaveFile, Pict );
  366.  
  367.   } else {
  368.     DispErrMsg("No Picture to save",0);
  369.     fclose(SaveFile);
  370.     return(UNSUCCESSFUL);
  371.   }
  372.  
  373.   fclose(SaveFile);
  374.  
  375.   if (FromWB) {
  376.  
  377.     FILE *IconFile;
  378.     char IconName[80];
  379.  
  380.     strcpy( IconName, SaveName );
  381.     strcat( IconName, ".info" );
  382.  
  383.     if ((IconFile = fopen( IconName, "r" )) == NULL) {
  384.  
  385.       /*
  386.        * OutPut an icon for the saved picture
  387.        */
  388.       if (Pict->pNode.ln_Type == MANDPICT)
  389.         (void) PutDiskObject(SaveName,&MandIcon);
  390.       else
  391.         (void) PutDiskObject(SaveName,&JuliaIcon);
  392.  
  393.     } else {
  394.       fclose( IconFile );
  395.     }
  396.   }
  397.  
  398.   return(SUCCESSFUL);
  399. } /* SaveCounts */
  400.  
  401. int
  402. WriteRLLTwo( SaveFile, Pict )
  403.   register FILE *SaveFile;
  404.   register struct Picture *Pict;
  405. {
  406.  
  407.   LONG Words;
  408.  
  409.   Words = Compress( Pict );
  410.  
  411.   fwrite( (char *) &Words, sizeof(LONG), 1, SaveFile);
  412.  
  413.   /* in case I ever recompile into 16 bit ints */
  414.  
  415.   if (sizeof(int) == 2 && sizeof(int)*Words > 65535) {
  416.     DispErrMsg("Programming error in Savemand\n", 0);
  417.     return(UNSUCCESSFUL);
  418.   }
  419.  
  420.   fwrite( (char *) Pict->Counts, (int) (sizeof(SHORT) * Words), 1, SaveFile);
  421.  
  422.   Decompress( Words, Pict );
  423.   return( SUCCESSFUL );
  424. }
  425.  
  426. /* Compress the data.  Count up how many words in a row have the same value.
  427.  * If the count is only one, then just put the data in the compressed array.
  428.  * Otherwise, turn on the most significant bit in the Count, and put it
  429.  * in the compressed array, then put the potential in the array.
  430.  *
  431.  * Advantages:
  432.  * -  Compressed data guaranteed to be as small or smaller than uncompressed
  433.  *    data.
  434.  * -  Compression can be done in place in memory, so it is fast without
  435.  *    requiring extra memory.
  436.  * -  Once compressed, the data can be written to disk with one fwrite,
  437.  *    therefore it should be quicker than previously used method that
  438.  *    compressed and wrote to disk at the same time.
  439.  * -  Maximum iteration count for Mandelbrot potential is 32767. The
  440.  *    previous method only allowed 1023.
  441.  */
  442. int
  443. Compress( Pict )
  444.   register struct Picture *Pict;
  445. {
  446.   register SHORT *CountPtr,*CompressPtr;
  447.   register SHORT  Count;
  448.   register USHORT Cur;
  449.   register ULONG  i;
  450.   register ULONG  Word = 0;
  451.  
  452.   i = Pict->CountsSize/sizeof(SHORT);
  453.  
  454.   CountPtr = CompressPtr = Pict->Counts;
  455.   Cur = *CountPtr;
  456.   Count = 1;
  457.  
  458.   while (--i) {
  459.     CountPtr++;
  460.  
  461.     /*
  462.      * Count up how many in a row have same height
  463.      */
  464.     if (Cur == *CountPtr) {
  465.       Count++;
  466.     } else {
  467.       if ( Count > 1 ) {
  468.         *CompressPtr++ = Count | 0x8000;
  469.       }
  470.       *CompressPtr++ = Cur;
  471.       Count = 1;
  472.       Cur = *CountPtr;
  473.     }
  474.   }
  475.  
  476.   if ( Count > 1 ) {
  477.     *CompressPtr++ = Count | 0x8000;
  478.   }
  479.   *CompressPtr++ = Cur;
  480.  
  481.   Word = CompressPtr - Pict->Counts;
  482.  
  483.   return( Word );
  484. }
  485.  
  486. /*
  487.  * Load the state of the program from file
  488.  */
  489. int
  490. LoadCounts(LoadName, Pict )
  491.   register char *LoadName;
  492.   register struct Picture *Pict;
  493. {
  494.   register FILE  *LoadFile;
  495.   USHORT ViewModes;
  496.   UBYTE  Depth;
  497.   char   Header[5];
  498.   ULONG  Version;
  499.   char   ErrMsg[80];
  500.   int    rc;
  501.   char  *File, *ExtractName();
  502.  
  503.   extern int Num_vp_Colors;
  504.   extern USHORT NewViewModes;
  505.   extern UBYTE  NewDepth;
  506.  
  507.   extern struct MathTransBase *MathTransBase;
  508.   extern LONG   SPTIEEE;
  509.  
  510.   /*
  511.    * Change the mouse pointer to Sleepy pointer
  512.    */
  513.  
  514.   SetSleepyPointer();
  515.  
  516.   LoadFile = fopen(LoadName,"r");
  517.  
  518.   Pict->GenState = FINISHEDSTATE;
  519.  
  520.   if (LoadFile == (FILE *) NULL) {
  521.  
  522.     /*
  523.      * can't read a non-existant file
  524.      */
  525.     sprintf(ErrMsg, "File %s not found", LoadName);
  526.     DispErrMsg(ErrMsg, 0);
  527.     return( UNSUCCESSFUL );
  528.   }
  529.  
  530.   /*
  531.    * Read and check the file header
  532.    */
  533.   (void) fread((char *) &Header[0], 4, 1, LoadFile);
  534.   Header[4] = '\0';
  535.  
  536.   if (strcmp(&Header[0], "MAND") != 0 &&
  537.       strcmp(&Header[0], "MAN1") != 0 &&
  538.       strcmp(&Header[0], "MAN2") != 0 &&
  539.       strcmp(&Header[0], "MAN3") != 0 &&
  540.       strcmp(&Header[0], "MAN4") != 0 &&
  541.       strcmp(&Header[0], "JUL3") != 0 &&
  542.       strcmp(&Header[0], "JUL4") != 0    ) {
  543.  
  544.     /*
  545.      * File of improper format
  546.      */
  547.     sprintf(ErrMsg, "File %s is not a MAND file",LoadName);
  548.     DispErrMsg(ErrMsg, 0);
  549.     fclose(LoadFile);
  550.     return( UNSUCCESSFUL );
  551.   }
  552.  
  553.   /*
  554.    * Read in the version
  555.    */
  556.   (void) fread((char *) &Version, sizeof(Version), 1, LoadFile);
  557.  
  558.   if ( strcmp( &Header[0], "MAN2") == 0 ||
  559.        strcmp( &Header[0], "MAN3") == 0 ||
  560.        strcmp( &Header[0], "MAN4") == 0 ||
  561.        strcmp( &Header[0], "JUL3") == 0 ||
  562.        strcmp( &Header[0], "JUL4") == 0 ) {
  563.  
  564.     if ( strcmp( &Header[0], "JUL3") == 0 ||
  565.          strcmp( &Header[0], "JUL4") == 0 ) {
  566.  
  567.       Pict->pNode.ln_Type = JULIAPICT;
  568.       (void) fread((char *) &Pict->Real, sizeof(double), 1, LoadFile);
  569.       (void) fread((char *) &Pict->Imag, sizeof(double), 1, LoadFile);
  570.     } else {
  571.       Pict->pNode.ln_Type = MANDPICT;
  572.     }
  573.  
  574.     /*
  575.      * Read in the location in the complex plane
  576.      */
  577.     (void) fread((char *) &Pict->RealLow,  sizeof(double), 1, LoadFile);
  578.     (void) fread((char *) &Pict->ImagLow,  sizeof(double), 1, LoadFile);
  579.     (void) fread((char *) &Pict->RealHigh, sizeof(double), 1, LoadFile);
  580.     (void) fread((char *) &Pict->ImagHigh, sizeof(double), 1, LoadFile);
  581.   } else {
  582.  
  583.     /* Must be old FFP code */
  584.  
  585.     LONG startx, starty, endx, endy;
  586.  
  587.     LONG SPTieee();
  588.  
  589.     /*
  590.      * Read in the FFP form of location in the complex plane
  591.      */
  592.     (void) fread((char *) &startx, sizeof(LONG), 1, LoadFile);
  593.     (void) fread((char *) &starty, sizeof(LONG), 1, LoadFile);
  594.     (void) fread((char *) &endx,   sizeof(LONG), 1, LoadFile);
  595.     (void) fread((char *) &endy,   sizeof(LONG), 1, LoadFile);
  596.  
  597.     /*
  598.      * Convert it to IEEE format
  599.      */
  600.     if (OpenFFPLibs() != 0)
  601.       return(UNSUCCESSFUL);
  602.  
  603.     startx = SPTieee( startx );
  604.     starty = SPTieee( starty );
  605.     endx   = SPTieee( endx );
  606.     endy   = SPTieee( endy );
  607.  
  608.     /*
  609.      * promote them to doubles
  610.      */
  611.     Pict->RealLow  = (double) *( (float *) &startx );
  612.     Pict->ImagLow  = (double) *( (float *) &starty );
  613.     Pict->RealHigh = (double) *( (float *) &endx );
  614.     Pict->ImagHigh = (double) *( (float *) &endy );
  615.   }
  616.  
  617.   /*
  618.    * Read in the maximum iteration count for a given point
  619.    */
  620.   (void) fread((char *) &Pict->MaxIteration, sizeof(SHORT), 1, LoadFile);
  621.  
  622.   /*
  623.    * Read in the generator type
  624.    */
  625.   (void) fread((char *) &Pict->MathMode, sizeof(Pict->MathMode), 1, LoadFile);
  626.  
  627.   /*
  628.    * Read in the calculation time
  629.    */
  630.   (void) fread((char *) &CalcTime, sizeof(CalcTime), 1, LoadFile);
  631.  
  632.   /*
  633.    * Read in the screen's viewmodes
  634.    */
  635.   (void) fread((char *) &ViewModes, sizeof(ViewModes), 1, LoadFile);
  636.  
  637.   ViewModes &= HIRES | INTERLACE | EXTRA_HALFBRITE;
  638.   Pict->ViewModes = ViewModes;
  639.  
  640.   /*
  641.    * Read in the number of bit planes
  642.    */
  643.   (void) fread((char *) &Depth, sizeof(Depth), 1, LoadFile);
  644.   Pict->Depth = Depth;
  645.  
  646.   /*
  647.    * Read in the window flags
  648.    */
  649.   (void) fread((char *) &BorderType, sizeof(BorderType), 1, LoadFile);
  650.  
  651.   /*
  652.    * Read in the color palette information
  653.    */
  654.   (void) fread((char *) &Pict->RGBs[0], sizeof(Pict->RGBs), 1, LoadFile);
  655.  
  656.   /*
  657.    * Read in the number of contours
  658.    */
  659.   (void) fread((char *) &NumContours, sizeof(NumContours), 1, LoadFile);
  660.  
  661.   /*
  662.    * Read in the heights
  663.    */
  664.   (void) fread((char *) Pict->Heights, sizeof(SHORT), NumContours, LoadFile);
  665.  
  666.   /*
  667.    * Read in the pen numbers (Color is a misnomer)
  668.    */
  669.   (void) fread((char *) Pict->Pens, sizeof(UBYTE), NumContours, LoadFile);
  670.  
  671.   for ( ; NumContours < NUMCONTS; NumContours++ ) {
  672.     *(Pict->Heights + NumContours) = 0;
  673.     *(Pict->Pens + NumContours) = 0;
  674.   }
  675.  
  676.   /*
  677.    * Read in the image dimensions
  678.    */
  679.   (void) fread((char *) &Pict->CountX,   sizeof(SHORT),  1, LoadFile);
  680.   (void) fread((char *) &Pict->CountY,   sizeof(SHORT),  1, LoadFile);
  681.  
  682.   if ( strcmp( &Header[0], "MAN4") == 0 ||
  683.        strcmp( &Header[0], "JUL4") == 0 ) {
  684.  
  685.     /*
  686.      * Read in the image dimensions
  687.      */
  688.     (void) fread((char *) &Pict->LeftEdge, sizeof(Pict->LeftEdge),
  689.                                            1, LoadFile);
  690.     (void) fread((char *) &Pict->TopEdge,  sizeof(Pict->TopEdge),
  691.                                            1, LoadFile);
  692.     (void) fread((char *) &Pict->CurLine,  sizeof(Pict->CurLine),
  693.                                            1, LoadFile);
  694.     if (Pict->CurLine > Pict->CountY)
  695.       Pict->CurLine -= TOPMARG;
  696.  
  697.   } else {
  698.     Pict->CurLine = Pict->CountY;
  699.   }
  700.  
  701.   GetCountsMemory( Pict );
  702.  
  703.   if (Pict->Counts == (SHORT *) NULL || (Pict->Flags & NO_RAM_GENERATE)) {
  704.     DispErrMsg("Can't load counts. Out of RAM!!",0);
  705.     fclose(LoadFile);
  706.     return( UNSUCCESSFUL );
  707.   }
  708.  
  709.   if ( strcmp( &Header[0], "MAN3") == 0 ||
  710.        strcmp( &Header[0], "MAN4") == 0 ||
  711.        strcmp( &Header[0], "JUL3") == 0 ||
  712.        strcmp( &Header[0], "JUL4") == 0 ) {
  713.  
  714.     rc = ReadRLLTwo( LoadFile, Pict );
  715.   } else {
  716.     rc = ReadRLLOne( LoadFile, Pict );
  717.   }
  718.   fclose(LoadFile);
  719.  
  720.   if (rc != SUCCESSFUL) {
  721.     return( rc );
  722.   }
  723.  
  724.   File = ExtractName( LoadName );
  725.   strncpy( Pict->Title, "  ", 2);
  726.   strncat( Pict->Title, File, sizeof(Pict->Title)-3);
  727.  
  728.   CalculateGaps( Pict );
  729.  
  730.   NewViewModes = Pict->ViewModes;
  731.   NewDepth     = Pict->Depth;
  732.  
  733.   if ( MaybeNewScreen() == 0 ) {
  734.  
  735.     /*
  736.      * Let's show it to them
  737.      */
  738.     if (OpenPicture( Pict ) != 0) {
  739.  
  740.       return( UNSUCCESSFUL );
  741.  
  742.     } else {
  743.       LoadRGB4( vp, Pict->RGBs, Num_vp_Colors );
  744.       ReColor( Pict );
  745.     }
  746.   }
  747.  
  748.   GetCurPict();
  749.  
  750.   if (CurPict) {
  751.     LoadRGB4( vp, CurPict->RGBs, Num_vp_Colors );
  752.   }
  753.   InitBorderSubs();
  754.  
  755.   return( SUCCESSFUL );
  756. } /* LoadCounts */
  757.  
  758. /* Load count information in pseudo RLL format */
  759. /* Bits 9-0 are iteration count.               */
  760. /* Bits 15-10 are how many iteration count of same height in a row */
  761.  
  762. int
  763. ReadRLLOne( LoadFile, Pict )
  764.   register FILE *LoadFile;
  765.   register struct Picture *Pict;
  766. {
  767.   register SHORT *CountPtr;
  768.   register LONG   i;
  769.   register ULONG  Count = 0;
  770.  
  771.   USHORT t;
  772.  
  773.   CountPtr = Pict->Counts;
  774.  
  775.   i = Pict->CountsSize / sizeof( SHORT );
  776.  
  777.   while (i > 0) {
  778.     if ( fread((char *) &t, sizeof(t), 1, LoadFile) == 0) {
  779.       DispErrMsg("Premature EOF on source file",0);
  780.       fclose(LoadFile);
  781.       return( UNSUCCESSFUL);
  782.     }
  783.     Count = t >> 10;
  784.     t = t & 0x3ff;
  785.  
  786.     for (; Count > 0; Count--) {
  787.      *(CountPtr++) = t;
  788.       i--;
  789.     }
  790.   }
  791.   return( SUCCESSFUL );
  792. }
  793.  
  794. int
  795. ReadRLLTwo( LoadFile, Pict )
  796.   register FILE *LoadFile;
  797.   register struct Picture *Pict;
  798. {
  799.   LONG Words;
  800.  
  801.   if (fread((char *) &Words, sizeof(Words), 1, LoadFile) == 0) {
  802.     DispErrMsg("Premature EOF on source file",0);
  803.     fclose(LoadFile);
  804.     return(UNSUCCESSFUL);
  805.   }
  806.   if (fread((char *) Pict->Counts,(int)(sizeof(SHORT)*Words),1,LoadFile) == 0){
  807.     DispErrMsg("Premature EOF on source file",0);
  808.     fclose(LoadFile);
  809.     return(UNSUCCESSFUL);
  810.   }
  811.   Decompress( Words, Pict );
  812.   return( SUCCESSFUL );
  813. }
  814.  
  815. /* This algorithm decompresses the data.  The data array has
  816.  * been malloced large enough to hold the decompressed data.  The data
  817.  * is read from the disk into the array in compressed format.  This
  818.  * decompresses the data in place.  The data must be decompressed from the
  819.  * back to the front.
  820.  */
  821. Decompress( Word, Pict )
  822.   LONG  Word;
  823.   struct Picture *Pict;
  824. {
  825.   register SHORT *CountPtr, *CompressPtr;
  826.   register SHORT  Count,Cur;
  827.   register LONG   i;
  828.   register SHORT  j;
  829.  
  830.   /* Point to the last word of compressed data */
  831.  
  832.   CompressPtr = Pict->Counts + Word - 1;
  833.  
  834.   i = Pict->CountsSize/sizeof(SHORT);
  835.  
  836.   /* Point to the last word of uncompressed data */
  837.  
  838.   CountPtr = Pict->Counts + i - 1;
  839.  
  840.   /* While there is data to uncompress.... */
  841.  
  842.   while (i > 1 && CountPtr >= Pict->Counts && CompressPtr >= Pict->Counts) {
  843.  
  844.     /* Pick up the last two words */
  845.  
  846.     Cur   = *CompressPtr--;
  847.     Count = *CompressPtr;
  848.  
  849.     if (Count & 0x8000) {        /* is it compressed? */
  850.  
  851.       Count &= 0x7fff;           /* extract count */
  852.  
  853.       for ( j = 0; j < Count; j++) {  /* Decompress it */
  854.         *CountPtr-- = Cur;
  855.         i--;
  856.       }
  857.       CompressPtr--;
  858.  
  859.     } else {
  860.  
  861.       *CountPtr-- = Cur;         /* just move it */
  862.       i--;
  863.     }
  864.   }
  865. }
  866.